import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.Semaphore;

public class BlockQueue<T> {
    private Queue<T> queue;

    private Semaphore popSem;

    private Semaphore addSem;

    BlockQueue(){
        this(Integer.MAX_VALUE);
    }

    BlockQueue(int maxLen){
        if(maxLen <= 0){
            throw new IllegalArgumentException();
        }
        queue = new LinkedList<>();
        addSem = new Semaphore(maxLen);
        popSem = new Semaphore(0);
    }

    public T pop() throws InterruptedException {
        T ele;
        popSem.acquire(); //如果没有元素可以获得，就一直阻塞。
        synchronized (queue){
            ele = queue.remove();
        }
        addSem.release(); //可以添加的数量++
        return ele;
    }

    public void add(T ele) throws InterruptedException {
        if(ele == null){
            throw new NullPointerException();
        }
        addSem.acquire(); //若没有空余位置加入，就一直阻塞。
        synchronized (queue) {
            queue.offer(ele);
        }
        popSem.release(); //可以获得的数量++
    }
}
